package com.tianyu.inspection.entity.model;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.tianyu.inspection.common.model.ListModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.*;

/**********************************
 * @Author YSW
 * @Description 请求实体模型
 * @Date 2021/1/11 - 17:18
 **********************************/

@Slf4j
@Data
@EqualsAndHashCode(callSuper = false)
public class QueryMo extends JSONObject {

    /**
     * 当前页数
     */
    private int pageNum = 1;

    /**
     * 单页数据条数
     */
    private int pageSize = 10;

    /**
     * 降序排序字段
     */
    private String descParams;

    /**
     * 升序字段
     */
    private String ascParams;

    /**
     * 精确匹配筛选字段
     */
    private ModelMap eqMap;

    /**
     * 集合匹配筛选字段
     */
    private Map<String, String> likeMap;

    /**
     * 集合匹配筛选字段
     */
    private Map<String, JSONArray> inMap;

    /**
     * SET 各字段数据
     *
     * @param type      数据筛选字段匹配目标对象
     * @param projectId 项目ID，筛选字段默认匹配
     * @param <T>       目标对象类型
     */
    public <T> QueryMo build(Class<T> type, Integer projectId) {
        likeMap = new HashMap<>();
        final String likeParams = this.getString("likeParams");
        if (likeParams != null) {
            final String[] params = likeParams.split(",");
            for (String param : params) {
                Field[] declaredFields = type.getDeclaredFields();
                final Optional<Field> first = Arrays.stream(declaredFields).filter(field -> {
                    field.setAccessible(true);
                    return field.getName().equals(param);
                }).findFirst();
                if (first.isPresent() && this.get(param) != null) {
                    this.likeMap.put(ListModel.getLineKeys(param), this.getString(param));
                }
            }
        }
        eqMap = new ModelMap();
        this.forEach((key, value) -> {
            if ("pageNum".equals(key)) {
                try {
                    setPageNum(Integer.parseInt(value.toString()));
                } catch (NumberFormatException e) {
                    log.error(String.valueOf(e));
                }
                return;
            }
            if ("pageSize".equals(key)) {
                try {
                    final int i = Integer.parseInt(value.toString());
                    if (i > 0) {
                        setPageSize(i);
                    } else if (i < 0) {
                        setPageSize(Integer.MAX_VALUE);
                    }
                } catch (NumberFormatException e) {
                    log.error(String.valueOf(e));
                }
                return;
            }
            if ("descParams".equals(key)) {
                if (Objects.nonNull(type)) {
                    setDescParams(paramFilter(type, (String) value));
                } else {
                    return;
                }
            }
            if ("ascParams".equals(key)) {
                if (Objects.nonNull(type)) {
                    setAscParams(paramFilter(type, (String) value));
                } else {
                    return;
                }
            }
            if (Objects.nonNull(type)) {
                Field[] declaredFields = type.getDeclaredFields();
                for (Field item : declaredFields) {
                    item.setAccessible(true);
                    if (key.equals(item.getName())) {
                        if (value != null && value != "") {
                            final String lineKey = ListModel.getLineKeys(item.getName());
                            if (!likeMap.containsKey(lineKey)) {
                                eqMap.put(lineKey, value);
                            }
                        }
                    }
                }
            }
        });
        /*
         * 存在项目ID的实体参数 & 非超级管理员的用户[项目ID不为1] 筛选项增加项目ID字段
         */
        if (Objects.nonNull(projectId) && projectId != 1) {
            this.put("projectId", projectId);
            eqMap.put("project_id", projectId);
            eqMap.put("state", 0);
        }
        /*
         * 存在项目ID的实体参数 & 超级管理员的用户[项目ID为0] 根据参数是否存在projectId字段决定筛选项是否增加项目ID字段
         */
        if (Objects.nonNull(this.get("projectId")) && Objects.nonNull(projectId) && projectId == 1) {
            eqMap.put("project_id", this.get("projectId"));
        }
        /*
         * 不存在项目ID的类型实体 添加state状态筛选字段筛选可用状态类型
         */
        if (Objects.isNull(projectId)) {
            eqMap.put("state", 0);
        }
        log.debug(this.toString());
        return this;
    }

    private <T> String paramFilter(Class<T> type, String value) {
        StringBuffer paramsBuffer = new StringBuffer();
        String[] values = value.split(",");
        Arrays.asList(values).forEach(param -> {
            Field[] declaredFields = type.getDeclaredFields();
            for (Field item : declaredFields) {
                item.setAccessible(true);
                if (param.equals(item.getName())) {
                    paramsBuffer.append(param).append(",");
                }
            }
        });
        if (paramsBuffer.length() <= 0) {
            return null;
        }
        String result = paramsBuffer.deleteCharAt(paramsBuffer.length() - 1).toString();
        return ListModel.getLineKeys(result);
    }

    public static QueryMo getQueryMo(HttpServletRequest request) {
        QueryMo queryMo = new QueryMo();
        Enumeration<String> parameterNames = request.getParameterNames();
        StringBuilder sb = new StringBuilder();
        while (parameterNames.hasMoreElements()) {
            String element = parameterNames.nextElement();
            queryMo.put(element, request.getParameter(element));
            sb.append(element).append("->").append(request.getParameter(element)).append(" | ");
        }
        String logInfo;
        if (sb.length() != 0) {
            sb.deleteCharAt(sb.lastIndexOf("|"));
            logInfo = "用户(" + request.getHeader("u-uid") + ") " + request.getMethod() + "请求 [ " + request.getRequestURI() + " ] 传入参数：" + sb.toString();
        } else {
            logInfo = "用户(" + request.getHeader("u-uid") + ") " + request.getMethod() + "请求 [ " + request.getRequestURI() + " ] 未传参数";
        }
        log.debug(logInfo);
        return queryMo;
    }
}
